{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"http://hilpisch.com/tpq_logo.png\" alt=\"The Python Quants\" width=\"35%\" align=\"right\" border=\"0\"><br><br><br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Listed Volatility and Variance Derivatives\n",
    "\n",
    "**Wiley Finance (2017)**\n",
    "\n",
    "Dr. Yves J. Hilpisch | The Python Quants GmbH\n",
    "\n",
    "http://tpq.io | [@dyjh](http://twitter.com/dyjh) | http://books.tpq.io\n",
    "\n",
    "<img src=\"http://hilpisch.com/../images/lvvd_cover.png\" alt=\"Derivatives Analytics with Python\" width=\"30%\" align=\"left\" border=\"0\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Trading and Settlement"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Introduction"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This chapter covers practical aspects of trading Eurex variance futures. Among others, topics are:\n",
    "\n",
    "* overview of major variance futures contract terms\n",
    "* intraday trading and trade conventions\n",
    "* trade matching at the end of the trading day\n",
    "* different traded volatilities with their impact on margining\n",
    "* after the trade matching until maturity\n",
    "* further details about interest rate calculation and market disruption events"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Overview of Variance Futures Terms"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The following listing provides an overview of the major terms of the Eurex variance futures contract. All technical terms are explained in chapter _Variance Futures_."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* **underlying**: realized variance of EURO STOXX 50 stock index \n",
    "* **interest rates**: Euribor for present value factor $DF_t$ and Eonia for $ARMVM_t$ \n",
    "* **standard strike**: determined on first trading day and equal to settled implied volatility for the relevant maturity\n",
    "* **1st settlement price**: equal to 3,000 (i.e. for setting standard strike = settled implied variance)\n",
    "* **contract value**: 1 EUR per variance futures point\n",
    "* **minimum price change/tick value**: 0.0001 variance futures points and 0.0001 EUR\n",
    "* **settlement**: in cash\n",
    "* **terms**: next three month ends and the next three quarter end months thereafter as well as June and December thereafter\n",
    "* **last trading day**: one day before final settlement day\n",
    "* **final settlement day/expiration**: third Friday of maturity month\n",
    "* **final settlement price**: based on the average index level of EURO STOXX 50 between 11:50 and 12:00 CET on final settlement day\n",
    "* **trade matching**: variance futures trade in notional vega at volatility; upon matching notional vega and volatility are converted into variance futures and variance futures prices, respectively\n",
    "* **continuous trading**: from 09:00 am until 5:30 pm CET on each trading day of Eurex\n",
    "* **Eurex trade entry services**: from 6:30 pm until 9:00 pm CET on each trading day of Eurex\n",
    "* **order maintainence**: notional vega at volatility, minimum order size 1 Vega, minimum price change 0.05 volatility points"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Intraday Trading"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Variance futures are traded on-exchange in terms of notional vega at volatility. However, intraday there are no live futures prices quoted, they have to be calculated using live volatility quotes and the conversion parameters provided by Eurex. The conversion parameters are those used for the calculation of the settlement price from the previous day, except that the time-to-maturity $(T-t)$ is reduced by 1 day and the number of elapsed days $t$ is increased by 1 day."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let us get back to the numerical example from section _Example Calculation_. The example simulates the calculation of daily settlement prices for a variance futures contract with inception on the 1st of June 2015 and a maturity on 19th of June 2015 (i.e. 15 trading days). Since we have saved the data, we can continue where we ended there."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "h5 = pd.HDFStore('./data/var_data.h5', 'r')\n",
    "data = h5['var_future']\n",
    "h5.close()\n",
    "data.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We need to read out two central terms of the variance, namely the time-to-maturity in year fractions and the  standard volatility strike."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "T = data['t'][-1]\n",
    "T"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "sigma_K = data['V6I1'][0]\n",
    "sigma_K"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Similar to the calculation in section _Example Calculation_, we can now do the following calculation where we use the previous day's input parameters but today's remaining time-to-maturity and today's elapsed time (in days). "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "data['F_ti'] = 3000.0\n",
    "for t in data.index[2:]:\n",
    "    data.loc[t, 'F_ti'] = data['DF_t'].shift(1)[t] * (\n",
    "                    (data['t'][t]  * data['sigma**2'].shift(1)[t]\n",
    "                  + (T - data['t'][t]) * data['V6I1'].shift(1)[t] ** 2) / T\n",
    "                  - sigma_K ** 2) - data['ARMVM_t'].shift(1)[t] + 3000"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The results are shown in the following table in the column ``F_ti`` for interim futures prices."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As an example, assume that a trader buys on the 9th of June intraday 100,000 notional Vega at a traded implied volatility level of 26. The number of futures she has bought then is\n",
    "\n",
    "\\begin{eqnarray*}\n",
    "futures &=& \\frac{VegaNotional}{2 \\cdot \\sigma_{ti}} \\cdot \\frac{T}{T-t} \\\\\n",
    "  &=& \\frac{100000}{2 \\cdot 26} \\cdot \\frac{15}{15-7} \\\\\n",
    "  &=& 3605.77\n",
    "\\end{eqnarray*}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "futures = 100000. / (2 * 26) * T / (T - data['t']['2015-06-09'])\n",
    "futures"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The intraday futures price for the variance futures contract is:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "F_ti = data['F_ti']['2015-06-09']\n",
    "F_ti"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The traded variance strike is\n",
    "\n",
    "\\begin{eqnarray*}\n",
    "\\sigma_t^2 &=& \\frac{t \\cdot \\sigma_{0,t}^2 + (T - t) \\cdot \\sigma_{i}^2(t, T)  }{T} \\\\\n",
    "     &=& \\frac{7 \\cdot 13.54^2 + (15 - 7) \\cdot 26^2  }{15} \\\\\n",
    "     &=& 446.08\n",
    "\\end{eqnarray*}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "sigma_t2 = (data['t']['2015-06-09'] * data['sigma**2']['2015-06-09']\n",
    "         + (T - data['t']['2015-06-09']) * 26 ** 2) / T\n",
    "sigma_t2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The traded futures price then is\n",
    "\n",
    "$$\n",
    "F_t = DF_t \\cdot \\left(\\sigma_t^2 -\\sigma_{i}^2(t,T) \\right) - ARMVM_t + 3000 = 2776.47\n",
    "$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "F_t = (data['DF_t']['2015-06-09'] *\n",
    "       (sigma_t2 - data['V6I1']['2015-06-01'] ** 2)\n",
    "              - data['ARMVM_t']['2015-06-09'] + 3000)\n",
    "F_t"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Consequently, the trade has a value of:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "P_ti = futures * F_t\n",
    "P_ti"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Trade Matching"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "At the end of the day, the trade in notional vega and volatility is confirmed. Notional vega and volatility are, however, converted into variance futures at the variance futures settlement price. To this end, the intraday transaction gets cancelled and replaced by a confirmed transaction with the same number of futures but with the variance futures settlement price of the day.\n",
    "\n",
    "In the example, we have"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "F_tS = data['F_tS']['2015-06-09']\n",
    "F_tS"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Consequently, the transaction booked has a value of:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "P_t = futures * F_tS\n",
    "P_t"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The first margin payment given these numbers then is: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "P_t - P_ti"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This is roughly the same as vega notional times the difference in settlement and traded volatility:\n",
    "\n",
    "$$\n",
    "margin = VegaNotional \\cdot (\\sigma_i - \\sigma_{i}(t,T))\n",
    "$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "100000 * (data['V6I1']['2015-06-09'] - 26)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Different Traded Volatilities"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let us now see what impact different traded volatilities have on the first day margining of the same trade as before. The necessary parameters and values can be calculated in vectorized fashion. First, the array with the traded volatilities."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "trad_vols = np.arange(15, 25.01, 1)\n",
    "trad_vols"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Second, the traded variance strikes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "sigma_t2 = (data['t']['2015-06-09'] * data['sigma**2']['2015-06-09']\n",
    "         + (T - data['t']['2015-06-09']) * trad_vols ** 2) / T\n",
    "sigma_t2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Third, the traded futures prices."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "F_t = (data['DF_t']['2015-06-09']\n",
    "       * (sigma_t2 - data['V6I1']['2015-06-01'] ** 2)\n",
    "               - data['ARMVM_t']['2015-06-09'] + 3000)\n",
    "F_t"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Fourth, the first day margins (P&L)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "margins = futures * (F_tS - F_t)\n",
    "margins"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let us visualize the results. The margins (P&L) are linear in traded volatility with the slope in the following figure being equal to the Vega notional of 100,000."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "from pylab import mpl, plt\n",
    "plt.style.use('seaborn')\n",
    "mpl.rcParams['font.family'] = 'serif'\n",
    "results = pd.DataFrame({'margins': margins}, index=trad_vols)\n",
    "results.plot(figsize=(10, 6));"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<p style=\"font-family: monospace;\">Variance futures margins."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## After the Trade Matching"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "What happens after the trade matching until maturity? To this end, we can calculate the subsequent margins as follows. We start with the differences between settlement prices."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "F_diffs = (data['F_tS'] - data['F_tS'].shift(1))\n",
    "F_diffs"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "With these differences, we can calculate the daily margins until maturity. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "margin_t = futures * F_diffs[F_diffs.index >= '2015-06-09']\n",
    "margin_t"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The following code generates a pandas ``DataFrame`` object with the initial margins given the traded volatility strike and the subsequent margins until maturity."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "results = pd.DataFrame(np.tile(margin_t, (len(trad_vols), 1)).T,\n",
    "                       index=margin_t.index,\n",
    "                       columns=trad_vols)\n",
    "results.loc['2015-06-09', :] = margins  # setting the first day margins\n",
    "np.round(results)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The following figure visualizes the cumulative P&L (assuming zero interest rates) for the different traded volatility strikes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "results.cumsum().plot(figsize=(10, 6), title='cumulative P&L');"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<p style=\"font-family: monospace;\">Cumulative P&L for variance future."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Further Details"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This section briefly discusses some further details of importance for the trading in Eurex variance futures."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Interest Rate Calculation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "ARMVM gets calculated based on the Eonia rate as settled at 7 pm CET on the previous day. The discount factors are calculated using the Euribor rates fixed at 11:00 am CET and interpolated to the respective maturities of the variance futures. The interpolation is done in linear fashion using the following formula:\n",
    "\n",
    "$$\n",
    "r_i = r(T_i) = \\frac{T_{K+1}-T_i}{T_{K+1}-T_K}r(T_K) + \\frac{T_i-T_K}{T_{K+1}-T_K}r(T_{K+1})\n",
    "$$\n",
    "\n",
    "where $T_{K+1}$ is maturity of the Euribor rate later than the futures maturity $T_i$, $T_K$ is the maturity of the Euribor rate before the futures maturity $T_i$."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Market Disruption Events"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "There are three major market disruption events:\n",
    "\n",
    "* STOXX fails to provide a market closing level for the EURO STOXX 50\n",
    "* Eurex Exchange fails to open for trading during scheduled trading hours\n",
    "* Other market disruption events according to the European OTC standard"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Conclusions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The major difference between listed variance futures and OTC variance swaps is that the former can be traded intraday. This chapter illustrates the major aspects that are important when it comes to the trading and settlement of these intraday-wise liquid instruments. Major concepts are the traded variance strike and the traded futures price. At the end of the day, the original intraday trade gets cancelled and the traded futures price gets replaced by the settlement price --- however, the number of futures remains the same."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"http://hilpisch.com/tpq_logo.png\" alt=\"The Python Quants\" width=\"35%\" align=\"right\" border=\"0\"><br>\n",
    "\n",
    "<a href=\"http://tpq.io\" target=\"_blank\">http://tpq.io</a> | <a href=\"http://twitter.com/dyjh\" target=\"_blank\">@dyjh</a> | <a href=\"mailto:team@tpq.io\">team@tpq.io</a>"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
